<template>
    <div>
        <canvas ref="canvasRef" width="500" height="500"></canvas>
    </div>
</template>
    
<script setup lang='ts'>
import { ref, onMounted } from 'vue'
import * as GLMat from 'gl-matrix'
console.log(GLMat);
const canvasRef = ref<HTMLCanvasElement>()

const renderPoint = () => {
    if (!canvasRef.value) return
    const webgl = canvasRef.value?.getContext('webgl') as WebGLRenderingContext;
    // 视图范围
    webgl.viewport(0, 0, canvasRef.value.clientWidth, canvasRef.value.clientHeight);
    // 坐标系转换关系
    const projMa4 = GLMat.mat4.create()
    GLMat.mat4.ortho(projMa4, 0, canvasRef.value.clientWidth, canvasRef.value.clientHeight, 0, -1.0, 1.0)

    // 着色器
    // 顶点着色器
    const vertexString = `
        // 用于接受js传递来的点的位置参数;
        attribute vec4 a_position;
        // 着色器中的坐标系
        uniform mat4 proj;
        void main(void){
            gl_Position = proj * a_position;
            gl_PointSize  = 4.0;
        }
    
    `
    // 片元着色器
    const fragmentString = `
     void main(void){
        gl_FragColor  = vec4(1.0,0,0,1.0);
     }
    `
    // shader
    const vsShader = webgl.createShader(webgl.VERTEX_SHADER);
    const fsShader = webgl.createShader(webgl.FRAGMENT_SHADER)
    if (!vsShader || !fsShader) return
    webgl.shaderSource(vsShader, vertexString);
    webgl.shaderSource(fsShader, fragmentString)


    // 编译
    webgl.compileShader(vsShader);
    webgl.compileShader(fsShader)

    // if (!webgl.getShaderParameter(vsShader, webgl.COMPILE_STATUS)) {
    //     var err = webgl.getShaderInfoLog(vsShader);
    //     alert(err);
    //     return;
    // }
    // if (!webgl.getShaderParameter(fsShader, webgl.COMPILE_STATUS)) {
    //     var err = webgl.getShaderInfoLog(fsShader);
    //     alert(err);
    //     return;
    // }


    // 创建着色器程序 由两个编译过后的 WebGLShader 组成 - 顶点着色器和片段着色器
    const program = webgl.createProgram();
    if (!program) return;
    webgl.attachShader(program, vsShader)
    webgl.attachShader(program, fsShader)

    // 使用着色器程序
    webgl.linkProgram(program);
    webgl.useProgram(program);


    // 设置点  平面点转为webgl点
    //设置点并加入顶点缓冲区：使用attribute和uniform传递数据（这里没有用缓冲区、因为只有一个点）
    const point = new Float32Array([100.0, 200.0, 0.0, 1.0])
    // 进行数据绑定  a_position 定义在顶点着色器中的变量
    const a_point_handler = webgl.getAttribLocation(program, 'a_position');
    // 配置项：位置、一次从顶点数组取几个数、顶点数组数据类型、是否归一化、间隔字节、偏移字节
    // webgl.vertexAttribPointer(a_point_handler, 3, webgl.FLOAT, false, 0, 0);
    // webgl.vertexAttribPointer(a_point_handler, 4, webgl.FLOAT, false, 0, 0);
    webgl.vertexAttrib4fv(a_point_handler, point)

    // 获取着色器变量赋值 转换关系
    const uniformLocartion = webgl.getUniformLocation(program, 'proj');
    if (!uniformLocartion) return;
    webgl.uniformMatrix4fv(uniformLocartion, false, projMa4)

    // 清空颜色缓冲
    webgl.clearColor(0, 0, 0, 1);
    // 清空缓存
    webgl.clear(webgl.COLOR_BUFFER_BIT) // 颜色缓冲区
    // webgl.clear(webgl.DEPTH_BUFFER_BIT ) // 深度缓冲区
    // webgl.clear(webgl.STENCIL_BUFFER_BIT  ) // 模板缓冲区

    webgl.drawArrays(webgl.POINTS, 0, 1)


    const points: number[] = []

    canvasRef.value.addEventListener('click', (event: PointerEvent) => {
        webgl.clearColor(0, 0, 0, 1);
        webgl.clear(webgl.COLOR_BUFFER_BIT) // 颜色缓冲区
        points.push(event.offsetX, event.offsetY)
        const clickPoint = new Float32Array(points);
        const bufferData = webgl.createBuffer();
        webgl.bindBuffer(webgl.ARRAY_BUFFER, bufferData);
        webgl.bufferData(webgl.ARRAY_BUFFER, clickPoint, webgl.STATIC_DRAW);
        webgl.enableVertexAttribArray(a_point_handler);
        webgl.vertexAttribPointer(a_point_handler, 2, webgl.FLOAT, false, clickPoint.BYTES_PER_ELEMENT * 2, 0);
        webgl.clearColor(0, 0, 0, 1);
        webgl.clear(webgl.COLOR_BUFFER_BIT | webgl.DEPTH_BUFFER_BIT);
        webgl.drawArrays(webgl.POINTS, 0, points.length/2)
    }, true)
}




onMounted(() => {
    renderPoint()
})
</script>
    
<style></style>